﻿using System;
using System.Collections.Generic;

namespace Framework.ObjectPool
{
    public class ObjectPoolManager : IModule, IObjectPoolManager
    {
        private Dictionary<string, ObjectPoolBase> pools = new Dictionary<string, ObjectPoolBase>();

        /// <summary>
        /// 获得对象池的数量
        /// </summary>
        public int Count
        {
            get
            {
                return pools.Count;
            }
        }
        /// <summary>
        /// 创建指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要创建的对象池的类型</typeparam>
        /// <returns>创建的对象池</returns>
        public IObjectPool<T> CreateObjectPool<T>() where T : ObjectBase, new()
        {
            return CreateObjectPool<T>(string.Empty);
        }
        /// <summary>
        /// 创建指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要创建的对象池的类型</typeparam>
        /// <param name="expireTime">对象池过期时间</param>
        /// <returns>创建的对象池</returns>
        public IObjectPool<T> CreateObjectPool<T>(float expireTime) where T : ObjectBase, new()
        {
            return CreateObjectPool<T>(string.Empty, expireTime);
        }
        /// <summary>
        /// 创建指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要创建的对象池的类型</typeparam>
        /// <param name="capatity">对象池容量</param>
        /// <returns>创建的对象池</returns>
        public IObjectPool<T> CreateObjectPool<T>(int capatity) where T : ObjectBase, new()
        {
            return CreateObjectPool<T>(string.Empty, capatity);
        }
        /// <summary>
        /// 创建指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要创建的对象池的类型</typeparam>
        /// <param name="name">对象池的名称</param>
        /// <returns>创建的对象池</returns>
        public IObjectPool<T> CreateObjectPool<T>(string name) where T : ObjectBase, new()
        {
            Type type = typeof(T);
            string typeName = string.IsNullOrEmpty(name) ? type.FullName : string.Format("{0}.{1}", type.FullName, name);
            if (pools.ContainsKey(typeName))
                return (IObjectPool<T>)pools[typeName];
            ObjectPool<T> objectPool = new ObjectPool<T>(typeName);
            pools.Add(typeName, objectPool);
            return objectPool;
        }
        /// <summary>
        /// 创建指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要创建的对象池的类型</typeparam>
        /// <param name="name">对象池的名称</param>
        /// <param name="expireTime">对象池过期时间</param>
        /// <returns>创建的对象池</returns>
        public IObjectPool<T> CreateObjectPool<T>(string name, float expireTime) where T : ObjectBase, new()
        {
            Type type = typeof(T);
            string typeName = string.IsNullOrEmpty(name) ? type.FullName : string.Format("{0}.{1}", type.FullName, name);
            if (pools.ContainsKey(typeName))
                return (IObjectPool<T>)pools[typeName];
            ObjectPool<T> objectPool = new ObjectPool<T>(typeName, expireTime);
            pools.Add(typeName, objectPool);
            return objectPool;
        }
        /// <summary>
        /// 创建指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要创建的对象池的类型</typeparam>
        /// <param name="name">对象池的名称</param>
        /// <param name="capatity">对象池的容量</param>
        /// <param name="expireTime">对象池过期时间</param>
        /// <returns>创建的对象池</returns>
        public IObjectPool<T> CreateObjectPool<T>(string name, int capatity, float expireTime) where T : ObjectBase, new()
        {
            Type type = typeof(T);
            string typeName = string.IsNullOrEmpty(name) ? type.FullName : string.Format("{0}.{1}", type.FullName, name);
            if (pools.ContainsKey(typeName))
                return (IObjectPool<T>)pools[typeName];
            ObjectPool<T> objectPool = new ObjectPool<T>(typeName, capatity, expireTime);
            pools.Add(typeName, objectPool);
            return objectPool;
        }
        /// <summary>
        /// 获得指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要获得的对象池的类型</typeparam>
        /// <returns>获得的对象池</returns>
        public IObjectPool<T> GetObjectPool<T>() where T : ObjectBase
        {
            return GetObjectPool<T>(string.Empty);
        }
        /// <summary>
        /// 获得指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要获得的对象池的类型</typeparam>
        /// <param name="name">对象池的名称</param>
        /// <returns>获得的对象池</returns>
        public IObjectPool<T> GetObjectPool<T>(string name) where T : ObjectBase
        {
            Type type = typeof(T);
            string typeName = string.IsNullOrEmpty(name) ? type.FullName : string.Format("{0}.{1}", type.FullName, name);
            if (pools.ContainsKey(typeName))
                return (IObjectPool<T>)pools[typeName];
            return null;
        }
        /// <summary>
        /// 是否存在指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要查询的对象池的类型</typeparam>
        /// <returns>是否存在指定类型的对象池</returns>
        public bool HasObjectPool<T>() where T : ObjectBase
        {
            return HasObjectPool<T>(string.Empty);
        }
        /// <summary>
        /// 是否存在指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要查询的对象池的类型</typeparam>
        /// <param name="name">对象池的名称</param>
        /// <returns>是否存在指定类型的对象池</returns>
        public bool HasObjectPool<T>(string name) where T : ObjectBase
        {
            Type type = typeof(T);
            string typeName = string.IsNullOrEmpty(name) ? type.FullName : string.Format("{0}.{1}", type.FullName, name);
            return pools.ContainsKey(typeName);
        }
        /// <summary>
        /// 销毁指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要销毁的对象池的类型</typeparam>
        public void DestroyObjectPool<T>() where T : ObjectBase
        {
            DestroyObjectPool<T>(string.Empty);
        }
        /// <summary>
        /// 销毁指定类型的对象池
        /// </summary>
        /// <typeparam name="T">要销毁的对象池的类型</typeparam>
        /// <param name="name">对象池的名称</param>
        public void DestroyObjectPool<T>(string name) where T : ObjectBase
        {
            Type type = typeof(T);
            string typeName = string.IsNullOrEmpty(name) ? type.FullName : string.Format("{0}.{1}", type.FullName, name);
            if(pools.ContainsKey(typeName))
            {
                IObjectPool<T> pool = (IObjectPool<T>)pools[typeName];
                pool.ReleaseAllObject();
                pools.Remove(typeName);
            }
        }
        int IModule.Priority
        {
            get
            {
                return ModulePriority.PoolPriority;
            }
        }
        public void Init()
        {
            
        }
        public void Destroy()
        {
            foreach (KeyValuePair<string, ObjectPoolBase> pool in pools)
            {
                pool.Value.Destroy();
            }
            pools.Clear();
        }
        public void Reset()
        {
            foreach (KeyValuePair<string, ObjectPoolBase> pool in pools)
            {
                pool.Value.Destroy();
            }
            pools.Clear();
        }
        public void Update(float frameTime, float realTime)
        {
            if (pools == null) return;
            foreach (KeyValuePair<string, ObjectPoolBase> pool in pools)
            {
                pool.Value.Update(frameTime, realTime);
            }
        }
    }
}
